package org.example.security;

import com.nimbusds.jose.*;
import com.nimbusds.jose.crypto.MACSigner;
import com.nimbusds.jose.crypto.MACVerifier;
import lombok.extern.slf4j.Slf4j;
import org.example.model.entity.User;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.nio.charset.StandardCharsets;
import java.security.SecureRandom;
import java.util.Map;

/**
 * JWT工具类
 *
 * @author RudeCrab
 */
@Slf4j
@Component
public class JwtManager {

    private final JWSHeader header = new JWSHeader(JWSAlgorithm.HS256);
    private final JWSSigner signer;
    private final JWSVerifier verifier;

    public JwtManager(@Value("${security.jwt.secretKey}") String secretKey) {
        try {
            SecureRandom random = new SecureRandom(secretKey.getBytes(StandardCharsets.UTF_8));
            byte[] sharedSecret = new byte[256 / 8];
            random.nextBytes(sharedSecret);
            signer = new MACSigner(sharedSecret);
            verifier = new MACVerifier(sharedSecret);
        } catch (JOSEException e) {
            throw new RuntimeException(e);
        }
    }

    public String generate(User user) {
        JWSObject jwsObject = new JWSObject(header, new Payload(Map.of("id", user.getId(), "username", user.getUsername())));
        try {
            jwsObject.sign(signer);
            return jwsObject.serialize();
        } catch (JOSEException e) {
            throw new RuntimeException(e);
        }
    }

    public User parse(String token) {
        if (token == null) return null;
        try {
            JWSObject jwsObject = JWSObject.parse(token);
            if (!jwsObject.verify(verifier))
                throw new JOSEException("token verify fail");
            Map<String, Object> json = jwsObject.getPayload().toJSONObject();
            return new User().setId(Integer.valueOf(json.get("id").toString())).setUsername(json.get("username").toString());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}
